# Required Packages
import pandas as pd
from pandas import Series, DataFrame
import numpy as np
import pandas_datareader.data as pdr
import math
from datetime import datetime
from datetime import timedelta
import matplotlib.dates as mdates
# Visualisation libraries
## Text
from colorama import Fore, Back, Style
from IPython.display import Image, display, Markdown, Latex, clear_output
## progressbar
import progressbar
## plotly
from plotly.offline import init_notebook_mode, iplot
import plotly.graph_objs as go
import plotly.offline as py
from plotly.subplots import make_subplots
import plotly.express as px
## seaborn
import seaborn as sns
## matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Polygon
from matplotlib.font_manager import FontProperties
plt.style.use('seaborn-whitegrid')
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
plt.rcParams['text.color'] = 'k'
%matplotlib inline
## WordCloud
from wordcloud import WordCloud
import warnings
warnings.filterwarnings("ignore")
In this article, the Cryptocurrencies from Yahoo! Finance is used, and we analyze the current top tech companies' stock prices.
| Symbol | Name | Symbol | Name |
|---|---|---|---|
| BTC-USD | Bitcoin USD | LTC-USD | Litecoin USD |
| ETH-USD | Ethereum USD | EOS-USD | EOS USD |
| XRP-USD | XRP USD | BNB-USD | Binance Coin USD |
| USDT-USD | Tether USD | XLM-USD | Stellar USD |
| BCH-USD | Bitcoin Cash USD | TRX-USD | TRON USD |
Stock_list = ['BTC-USD','ETH-USD','XRP-USD','USDT-USD','BCH-USD','LTC-USD','EOS-USD','BNB-USD','XLM-USD','TRX-USD']
Stock_Dic = {'BTC-USD':'Bitcoin USD', 'ETH-USD':'Ethereum USD','XRP-USD':'XRP USD','USDT-USD':'Tether USD',
'BCH-USD':'Bitcoin Cash USD','LTC-USD':'Litecoin USD','EOS-USD':'EOS USD',
'BNB-USD':'Binance Coin USD','XLM-USD':'Stellar USD','TRX-USD':'TRON USD'}
The data is collected from a years ago until now.
#start, end = [datetime(datetime.today().year-2, 1, 1), datetime.today()]
start, end = [datetime(datetime.today().year-1,datetime.today().month,datetime.today().day), datetime.today()]
def Timeline_plot(start, end, width = 16):
fig, ax = plt.subplots(figsize=(width, 1))
Temp = pd.date_range(start, datetime(end.year, end.month, 1), freq='MS')
ax.plot((start, end), (0, 0), 'k', alpha=.5)
ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=2))
ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y"))
#fig.autofmt_xdate()
_ = plt.setp((ax.get_yticklabels() + ax.get_yticklines() + list(ax.spines.values())), visible=False)
for i in Temp:
ax.scatter(i, 0, s=30, facecolor='#e74c3c', edgecolor='k')
ax.grid(False)
_ = plt.xticks(rotation=90)
Temp1 = Temp.min().replace(day=1) - timedelta(days=1)
Temp2 = Temp.max().replace(day=1) + timedelta(days=31)
_ = ax.set_xlim ([datetime(Temp1.year,Temp1.month, 1), datetime(Temp2.year,Temp2.month, 1)])
Timeline_plot(start, end)
Collecting data from Yahoo Finance!, and creating moving Averages for 10, 20 and 60 day periods of time.
def Get_Data(Inp):
Days = [10, 20, 60]
Out = pdr.DataReader(Inp, 'yahoo', start, end)
Out.insert(0, 'Symbol', Inp)
for j in Days:
column_name = "Moving Ave. %s days" % (str(j))
Out[column_name] = Out['Adj Close'].rolling(window=j, center=False).mean()
return Out
Data = Get_Data(Stock_list[0])
Counter = 0
Progress_Bar = progressbar.ProgressBar(maxval=len(Stock_list),
widgets=[progressbar.Bar('#', '|', '|'), progressbar.Percentage()])
Progress_Bar.start()
for i in Stock_list[1:]:
Counter+=1
Progress_Bar.update(Counter)
Temp = Get_Data(i)
Data = pd.concat([Data, Temp])
del Temp
Progress_Bar.finish()
|#########################################################################|100%
Displaying today's data only:
Today = Data[Data.index == Data.index[-1]].reset_index(drop = True)
Today.style.hide_index()
| Symbol | High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days |
|---|---|---|---|---|---|---|---|---|---|
| BTC-USD | 63742.285156 | 59892.859375 | 60292.875000 | 63450.253906 | 65953972224.000000 | 63450.253906 | 59196.859375 | 58120.252930 | 54613.532096 |
| ETH-USD | 2312.880859 | 2139.883789 | 2199.374512 | 2305.832764 | 26476500992.000000 | 2305.832764 | 2118.993396 | 1981.449573 | 1812.322996 |
| XRP-USD | 1.868102 | 1.423034 | 1.443494 | 1.863740 | 28023173120.000000 | 1.863740 | 1.172106 | 0.870109 | 0.616955 |
| USDT-USD | 1.001035 | 0.998829 | 1.000515 | 1.000897 | 129010933760.000000 | 1.000897 | 1.001194 | 1.001009 | 1.000734 |
| BCH-USD | 748.496887 | 671.575745 | 744.038513 | 744.019897 | 4004313088.000000 | 744.019897 | 657.406317 | 592.082475 | 573.998638 |
| LTC-USD | 272.572968 | 244.934692 | 248.769913 | 271.211670 | 6569492480.000000 | 271.211670 | 235.602661 | 214.318525 | 204.166118 |
| EOS-USD | 7.528289 | 6.423983 | 6.455691 | 7.406473 | 3453297664.000000 | 7.406473 | 6.549685 | 5.622094 | 4.652438 |
| BNB-USD | 602.091675 | 534.800842 | 572.135071 | 556.723267 | 10443403264.000000 | 556.723267 | 452.225513 | 371.829871 | 283.627731 |
| XLM-USD | 0.672736 | 0.577618 | 0.631182 | 0.659734 | 3788909568.000000 | 0.659734 | 0.538437 | 0.472185 | 0.443655 |
| TRX-USD | 0.154118 | 0.128340 | 0.132068 | 0.150680 | 7471161856.000000 | 0.150680 | 0.126782 | 0.100981 | 0.068896 |
print('Currently, the stock with the highest volume is %s' %
Stock_Dic[Today[Today.Volume == Today.Volume.max()].Symbol.values[0]])
Currently, the stock with the highest volume is Tether USD
Consider BTC-USD for example. We hAve,
def Disp_Data(Inp, df = Data):
Out = df[df.Symbol == Inp].drop(columns=['Symbol'])
return Out
def Header(Text, L = 100, C1 = Back.BLUE, C2 = Fore.BLUE):
print(C1 + Fore.WHITE + Style.NORMAL + Text + Style.RESET_ALL + ' ' + C2 +
Style.NORMAL + (L- len(Text) - 1)*'=' + Style.RESET_ALL)
def Line(L=100, C = Fore.BLUE): print(C + Style.NORMAL + L*'=' + Style.RESET_ALL)
Temp = Disp_Data('BTC-USD')
display(Temp.describe())
Header('Last Year')
display(Temp.head(7).dropna(axis = 1))
Header('This Week')
display(Temp.tail(7))
del Temp
Line()
| High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days | |
|---|---|---|---|---|---|---|---|---|---|
| count | 362.000000 | 362.000000 | 362.000000 | 362.000000 | 3.620000e+02 | 362.000000 | 353.000000 | 343.000000 | 303.000000 |
| mean | 22713.823712 | 21436.431943 | 22053.565616 | 22201.609826 | 4.049166e+10 | 22201.609826 | 21914.791260 | 21593.312747 | 20203.018076 |
| std | 17494.125583 | 16306.002636 | 16897.032525 | 17011.341006 | 2.573819e+10 | 17011.341006 | 16526.425000 | 15987.477950 | 13673.311590 |
| min | 6928.664551 | 6555.504395 | 6640.454102 | 6642.109863 | 1.225260e+10 | 6642.109863 | 7020.268311 | 7640.823535 | 8828.262402 |
| 25% | 9826.263428 | 9493.564697 | 9676.830078 | 9682.938477 | 2.366986e+10 | 9682.938477 | 9659.388867 | 9619.520166 | 10488.472664 |
| 50% | 12031.534180 | 11686.394043 | 11872.355957 | 11878.241699 | 3.439372e+10 | 11878.241699 | 11834.882617 | 11747.914844 | 12233.265918 |
| 75% | 34630.800781 | 31912.527344 | 33082.373047 | 33087.209961 | 5.227154e+10 | 33087.209961 | 33508.347656 | 34068.854199 | 27807.690202 |
| max | 63742.285156 | 59892.859375 | 61221.132812 | 63450.253906 | 3.509679e+11 | 63450.253906 | 59196.859375 | 58120.252930 | 54613.532096 |
Last Year ==========================================================================================
| High | Low | Open | Close | Volume | Adj Close | |
|---|---|---|---|---|---|---|
| Date | ||||||
| 2020-04-12 | 6965.616699 | 6668.259766 | 6965.616699 | 6845.037598 | 3.861931e+10 | 6845.037598 |
| 2020-04-13 | 6958.557129 | 6793.821289 | 6843.281738 | 6842.427734 | 3.411043e+10 | 6842.427734 |
| 2020-04-14 | 6928.664551 | 6633.402832 | 6845.561523 | 6642.109863 | 3.228831e+10 | 6642.109863 |
| 2020-04-15 | 7134.450684 | 6555.504395 | 6640.454102 | 7116.804199 | 4.678324e+10 | 7116.804199 |
| 2020-04-17 | 7269.956543 | 7089.247070 | 7092.291504 | 7257.665039 | 3.244719e+10 | 7257.665039 |
| 2020-04-18 | 7280.521973 | 7167.054688 | 7260.922363 | 7189.424805 | 3.131121e+10 | 7189.424805 |
| 2020-04-19 | 7240.290527 | 6835.502930 | 7186.873535 | 6881.958496 | 3.774711e+10 | 6881.958496 |
This Week ==========================================================================================
| High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days | |
|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||
| 2021-04-06 | 58731.144531 | 55604.023438 | 58186.507812 | 56048.937500 | 7.564530e+10 | 56048.937500 | 58372.846484 | 56936.013477 | 53146.907357 |
| 2021-04-07 | 58338.738281 | 55879.085938 | 56099.914062 | 58323.953125 | 5.305386e+10 | 58323.953125 | 58430.221875 | 56934.878516 | 53470.582552 |
| 2021-04-08 | 58937.046875 | 57807.863281 | 58326.562500 | 58245.003906 | 4.665521e+10 | 58245.003906 | 58362.953125 | 56931.446484 | 53671.391536 |
| 2021-04-09 | 61276.664062 | 58038.707031 | 58253.777344 | 59793.234375 | 5.823847e+10 | 59793.234375 | 58450.393359 | 57044.937109 | 53893.260352 |
| 2021-04-10 | 60790.554688 | 59289.796875 | 59846.230469 | 60204.964844 | 4.628025e+10 | 60204.964844 | 58561.308984 | 57328.728125 | 54148.040039 |
| 2021-04-11 | 61253.035156 | 59589.875000 | 60175.945312 | 59893.453125 | 5.182869e+10 | 59893.453125 | 58612.223047 | 57586.453516 | 54347.775391 |
| 2021-04-13 | 63742.285156 | 59892.859375 | 60292.875000 | 63450.253906 | 6.595397e+10 | 63450.253906 | 59196.859375 | 58120.252930 | 54613.532096 |
====================================================================================================
Let's plot the stocks adjusted the closing price for all stock data under study.
Temp = Data[['Symbol','Adj Close']].reset_index(drop = False)
fig = px.line(Data.reset_index(drop = False), x='Date', y='Adj Close', color= 'Symbol')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='A Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + 'Stock Prices Fluctuations' + '<b>',
'x':.5, 'y': .95, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
del Temp
The following table shows the Average values for all columns of the Data.
def List_Search(List, Key): return [s for s in List if Key in s]
def List_Diff(Inp_A, Inp_B):
# Inp_A: A list
# Inp_B: A list
Out=list(set(Inp_A)-set(Inp_B))
return Out
# Creating a new list of Columns
Columns = List_Diff(Data.columns.tolist(), List_Search(Data.columns.tolist(), 'Moving Ave'))
Columns = List_Diff(Columns, ['Symbol'])
Temp = ['Ave. ' + i for i in Columns]
# A new DataFrame
Ave_df = pd.DataFrame({'Symbol':Stock_list})
for i in Temp:
Ave_df[i]=''
del Temp
# Progress Bar
Counter = 0
Progress_Bar = progressbar.ProgressBar(maxval=len(Stock_list),
widgets=[progressbar.Bar('#', '|', '|'), progressbar.Percentage()])
Progress_Bar.start()
for i in range(len(Stock_list)):
Counter+=1
Progress_Bar.update(Counter)
Ave_df.iloc[i,1:] = Data[Data.Symbol == Stock_list[i]][Columns].mean().values
Progress_Bar.finish()
Ave_df [list(set(Ave_df.columns)-{'Symbol'})] = Ave_df [list(set(Ave_df.columns)-{'Symbol'})].astype(float)
display(Ave_df.style.hide_index())
Temp = pd.melt(Ave_df, id_vars=['Symbol'], value_vars=list(set(Ave_df.columns)-{'Symbol'}),
var_name='Summary', value_name='Value')
|#########################################################################|100%
| Symbol | Ave. Low | Ave. Close | Ave. Adj Close | Ave. High | Ave. Open | Ave. Volume |
|---|---|---|---|---|---|---|
| BTC-USD | 21436.431943 | 22201.609826 | 22201.609826 | 22713.823712 | 22053.565616 | 40491657860.345306 |
| ETH-USD | 682.914129 | 714.503764 | 714.503764 | 735.222990 | 708.986783 | 18829598862.223759 |
| XRP-USD | 0.318386 | 0.337756 | 0.337756 | 0.352824 | 0.333071 | 5052734910.461326 |
| USDT-USD | 0.997676 | 1.001218 | 1.001218 | 1.005675 | 1.001224 | 62589707700.096687 |
| BCH-USD | 319.523905 | 333.183416 | 333.183416 | 344.626460 | 332.086941 | 3279277536.132596 |
| LTC-USD | 88.195906 | 92.484729 | 92.484729 | 95.761944 | 91.891936 | 4514179108.779005 |
| EOS-USD | 2.974810 | 3.098761 | 3.098761 | 3.204888 | 3.085786 | 2816217061.328729 |
| BNB-USD | 65.158292 | 69.817798 | 69.817798 | 72.783758 | 68.268006 | 1148828516.817680 |
| XLM-USD | 0.166528 | 0.176034 | 0.176034 | 0.184229 | 0.174590 | 883005536.099447 |
| TRX-USD | 0.029913 | 0.031479 | 0.031479 | 0.032724 | 0.031114 | 1660731938.455801 |
fig = make_subplots(rows=2, cols=1, vertical_spacing = 0.1, shared_yaxes=True,
subplot_titles=('Ave. Volume', 'Summary'))
# Top
fig1 = px.bar(Ave_df.round(0), x= 'Symbol', y= 'Ave. Volume', orientation='v', text = 'Ave. Volume',
hover_data= Ave_df.columns)
for i in range(len(fig1['data'])):
fig.add_trace(fig1['data'][i], row=1, col=1)
fig.update_traces(marker_line_color= 'Black', marker_line_width=1, opacity=1, row=1, col=1)
# Bottom
fig2 = px.bar(Temp.loc[Temp.Summary != 'Ave. Volume'].round(0), x= 'Symbol', y = 'Value',
color = 'Summary', orientation='v', hover_data= Temp.columns)
for i in range(len(fig2['data'])):
fig.add_trace(fig2['data'][i], row=2, col=1)
fig.update_traces(marker_line_color= 'Black', marker_line_width=1, opacity=1, showlegend = True, row=2, col=1)
# Update
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
zeroline=False, zerolinewidth=1, zerolinecolor='Black',
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
zeroline=False, zerolinewidth=1, zerolinecolor='Black', title_text='Value',
showgrid=False, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(legend_orientation='v', plot_bgcolor= 'white', height= 800)
fig.update_layout(legend=dict(font=dict(color="Black"), bordercolor="Lightgray", borderwidth=1))
fig.update_layout(title={'text': '<b>' + 'Average Values' + '<b>', 'x':0.5, 'y': .95, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
Let's plot moving Averages for 10, 20 and 60 day periods of time for the top 4 companies with the highest volume on Average.
def TopN_volumes(N, df = Ave_df):
Out = df.sort_values(by='Ave. Volume', ascending=False).iloc[:N,0].tolist()
return Out
# Conisder the Moving Ave and Adj Close columns
Columns = List_Search(Data.columns.tolist(), 'Moving Ave.')
Columns.append("Adj Close")
Columns = list(np.sort(Columns))
# A list of top N = 4 companies with the hightest volume on Average.
N = 4
mylist = TopN_volumes(N)
# Conisder the Moving Ave and Adj Close columns
Columns = List_Search(Data.columns.tolist(), 'Moving Ave.')
Columns.append("Adj Close")
Columns = list(np.sort(Columns))
# A list of top N = 4 companies with the hightest volume on Average.
N = 4
mylist = Ave_df.sort_values(by='Ave. Volume', ascending=False).iloc[:N,0].tolist()
for stock in mylist:
Temp = Disp_Data(stock)[Columns].reset_index(drop = False)
Temp = pd.melt(Temp, id_vars=['Date'], value_vars= List_Diff(Temp.columns, ['Date']),
var_name='Variable', value_name='Value')
fig = px.line(Temp, x='Date', y='Value', color = 'Variable')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='A Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + stock + '<b>',
'x':.5, 'y': .95, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
del Temp
del stock
Daily return can be calculated using the percentage change of the adjusted closing price.
Daily_Return = Disp_Data(mylist[0])['Adj Close'].pct_change().to_frame('Daily Return').reset_index(drop = False)
Daily_Return['Symbols'] = mylist[0]
for stock in mylist[1:]:
Temp = Disp_Data(stock)['Adj Close'].pct_change().to_frame('Daily Return').reset_index(drop = False)
Temp['Symbols'] = stock
Daily_Return = pd.concat([Daily_Return, Temp])
del Temp, stock
Daily_Return = Daily_Return.sort_values('Date')
fig = px.line(Daily_Return, x='Date', y='Daily Return', color = 'Symbols')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='A Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + 'Daily Returns' + '<b>',
'x':.5, 'y': .95, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
del Daily_Return
First, we need to create a new data frame by reading the Adj Close column from all stock data under study. We hAve,
All_data = pdr.DataReader(Stock_list, 'yahoo', start, end)['Adj Close']
All_returns = All_data.pct_change()
Header('Last Year')
display(All_data.head(7).dropna(axis = 1))
Header('This Week')
display(All_data.tail(7))
Line()
Last Year ==========================================================================================
| Symbols | BTC-USD | ETH-USD | XRP-USD | USDT-USD | BCH-USD | LTC-USD | EOS-USD | BNB-USD | XLM-USD | TRX-USD |
|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||
| 2020-04-12 | 6845.037598 | 156.279556 | 0.187732 | 1.000327 | 223.851898 | 41.204342 | 2.445054 | 15.034427 | 0.048339 | 0.012585 |
| 2020-04-13 | 6842.427734 | 157.596390 | 0.185335 | 0.996806 | 221.970337 | 41.053841 | 2.456288 | 15.525076 | 0.048215 | 0.012413 |
| 2020-04-14 | 6642.109863 | 153.286896 | 0.181270 | 0.999529 | 215.506866 | 39.589069 | 2.402014 | 14.593927 | 0.046409 | 0.012225 |
| 2020-04-15 | 7116.804199 | 172.157379 | 0.190104 | 1.002719 | 235.592773 | 42.689018 | 2.655668 | 15.702730 | 0.049125 | 0.013042 |
| 2020-04-17 | 7257.665039 | 186.914001 | 0.194925 | 1.000777 | 243.078995 | 44.362896 | 2.728006 | 16.593172 | 0.050501 | 0.013369 |
| 2020-04-18 | 7189.424805 | 181.614960 | 0.190859 | 1.007704 | 233.588791 | 42.634750 | 2.620096 | 16.139933 | 0.049209 | 0.013032 |
| 2020-04-19 | 6881.958496 | 172.297165 | 0.183490 | 1.004804 | 221.568283 | 40.828384 | 2.524980 | 15.085403 | 0.049997 | 0.012517 |
This Week ==========================================================================================
| Symbols | BTC-USD | ETH-USD | XRP-USD | USDT-USD | BCH-USD | LTC-USD | EOS-USD | BNB-USD | XLM-USD | TRX-USD |
|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||
| 2021-04-06 | 56048.937500 | 1971.077271 | 0.917576 | 1.001855 | 618.597534 | 219.423676 | 5.878462 | 374.658813 | 0.473280 | 0.110282 |
| 2021-04-07 | 58323.953125 | 2088.573730 | 1.052756 | 1.000167 | 647.564087 | 227.003021 | 6.439491 | 418.038391 | 0.506816 | 0.123070 |
| 2021-04-08 | 58245.003906 | 2072.108887 | 1.020837 | 1.001098 | 635.706726 | 221.862366 | 6.214584 | 453.178467 | 0.486387 | 0.115934 |
| 2021-04-09 | 59793.234375 | 2135.942139 | 1.374416 | 1.000469 | 673.957581 | 255.620193 | 6.611337 | 472.560333 | 0.561829 | 0.125983 |
| 2021-04-10 | 60204.964844 | 2157.656982 | 1.360530 | 1.002177 | 696.608459 | 253.634460 | 6.744065 | 525.385559 | 0.588810 | 0.122353 |
| 2021-04-11 | 59893.453125 | 2139.353271 | 1.467735 | 0.999937 | 674.786255 | 244.494370 | 6.482461 | 598.722656 | 0.590592 | 0.129048 |
| 2021-04-13 | 63450.253906 | 2305.832764 | 1.863740 | 1.000897 | 744.019897 | 271.211670 | 7.406473 | 556.723267 | 0.659734 | 0.150680 |
====================================================================================================
The returns can be analyzed using the percentage change from the adj Close.
Header('Returns This Week', C1 = Back.GREEN, C2 = Fore.GREEN)
display(All_returns.tail(7))
Temp = pd.melt(All_returns.reset_index(drop = False), id_vars=['Date'],
value_vars=list(set(All_returns.columns)-{'Date'}),
var_name='Symbols', value_name='Daily Return')
fig = px.line(Temp, x='Date', y='Daily Return', color = 'Symbols')
fig.update_xaxes(rangeslider_visible=True, rangeslider =dict(bgcolor = 'WhiteSmoke'),
rangeselector=dict(bgcolor='WhiteSmoke', buttons=list([
dict(count=1, label='One Day', step='day', stepmode='todate'),
dict(count=7, label='One Week', step='day', stepmode='todate'),
dict(count=1, label='One Month', step='month', stepmode='todate'),
dict(count=6, label='Six Months', step='month', stepmode='todate'),
dict(count=1, label='A Year', step='year', stepmode='todate'),dict(step='all')])))
fig.update_layout(plot_bgcolor= 'white')
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(title={'text': '<b>' + 'Daily Returns' + '<b>',
'x':.5, 'y': .98, 'xanchor': 'center', 'yanchor': 'top'})
fig.show()
Returns This Week ==================================================================================
| Symbols | BTC-USD | ETH-USD | XRP-USD | USDT-USD | BCH-USD | LTC-USD | EOS-USD | BNB-USD | XLM-USD | TRX-USD |
|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||
| 2021-04-06 | -0.036833 | -0.069535 | -0.162999 | 0.000175 | -0.073607 | -0.076752 | -0.117910 | -0.071686 | -0.127987 | -0.113303 |
| 2021-04-07 | 0.040590 | 0.059610 | 0.147323 | -0.001685 | 0.046826 | 0.034542 | 0.095438 | 0.115784 | 0.070859 | 0.115957 |
| 2021-04-08 | -0.001354 | -0.007883 | -0.030319 | 0.000931 | -0.018311 | -0.022646 | -0.034926 | 0.084059 | -0.040309 | -0.057983 |
| 2021-04-09 | 0.026581 | 0.030806 | 0.346362 | -0.000628 | 0.060171 | 0.152157 | 0.063842 | 0.042769 | 0.155107 | 0.086679 |
| 2021-04-10 | 0.006886 | 0.010166 | -0.010103 | 0.001707 | 0.033609 | -0.007768 | 0.020076 | 0.111785 | 0.048024 | -0.028813 |
| 2021-04-11 | -0.005174 | -0.008483 | 0.078797 | -0.002235 | -0.031326 | -0.036036 | -0.038790 | 0.139587 | 0.003026 | 0.054719 |
| 2021-04-13 | 0.059385 | 0.077818 | 0.269807 | 0.000960 | 0.102601 | 0.109276 | 0.142540 | -0.070148 | 0.117073 | 0.167627 |
The following graphs show the correlation between different stocks.
_ = sns.jointplot('BTC-USD','XRP-USD', All_returns, kind='reg', space=0, size=6, ratio=4)
_ = sns.jointplot('BTC-USD','ETH-USD', All_returns, kind='reg', space=0, size=6, ratio=4)
Now, we can use the pairplot tool to visualize all.
# Remove missing values
Temp = TopN_volumes(8, df = Ave_df)
Temp = All_returns[Temp].dropna()
# plot
_ = sns.pairplot(Temp, diag_kind='kde')
Nonetheless, the correlation matrix and plot are always convenient to see numerical values for correlations.
# Correlation Matrix
Cor_matrix = Temp.corr()
display(Cor_matrix)
def Correlation_Plot (Df,Fig_Size):
Correlation_Matrix = Df.corr()
mask = np.zeros_like(Correlation_Matrix)
mask[np.triu_indices_from(mask)] = True
for i in range(len(mask)):
mask[i,i]=0
Fig, ax = plt.subplots(figsize=(Fig_Size,Fig_Size))
sns.heatmap(Correlation_Matrix, ax=ax, mask=mask, annot=True, square=True,
cmap =sns.color_palette("RdBu", n_colors=10), linewidths = 0.2, vmin=0, vmax=1, cbar_kws={"shrink": .5})
bottom, top = ax.get_ylim()
_ = ax.set_ylim(bottom + 0.5, top - 0.5)
Correlation_Plot (Temp, 10)
| Symbols | USDT-USD | BTC-USD | ETH-USD | XRP-USD | LTC-USD | BCH-USD | EOS-USD | TRX-USD |
|---|---|---|---|---|---|---|---|---|
| Symbols | ||||||||
| USDT-USD | 1.000000 | -0.023659 | -0.015063 | -0.024688 | -0.024636 | -0.022108 | -0.032235 | -0.003708 |
| BTC-USD | -0.023659 | 1.000000 | 0.711595 | 0.327867 | 0.732262 | 0.649706 | 0.569419 | 0.438653 |
| ETH-USD | -0.015063 | 0.711595 | 1.000000 | 0.404182 | 0.749583 | 0.737850 | 0.654182 | 0.547493 |
| XRP-USD | -0.024688 | 0.327867 | 0.404182 | 1.000000 | 0.474553 | 0.501913 | 0.581606 | 0.430522 |
| LTC-USD | -0.024636 | 0.732262 | 0.749583 | 0.474553 | 1.000000 | 0.774271 | 0.706092 | 0.479978 |
| BCH-USD | -0.022108 | 0.649706 | 0.737850 | 0.501913 | 0.774271 | 1.000000 | 0.782005 | 0.525552 |
| EOS-USD | -0.032235 | 0.569419 | 0.654182 | 0.581606 | 0.706092 | 0.782005 | 1.000000 | 0.629073 |
| TRX-USD | -0.003708 | 0.438653 | 0.547493 | 0.430522 | 0.479978 | 0.525552 | 0.629073 | 1.000000 |
Here, darker shades of blue represent a higher correlation.
Temp = All_returns.mean().to_frame('Expected Return').join(All_returns.std().to_frame('Risk')).reset_index(drop = False)
fig = px.scatter(Temp, x= 'Expected Return', y='Risk', color= 'Symbols',
size='Expected Return', hover_data=Temp.columns)
fig.update_traces(marker_line_color= 'Black', marker_line_width=1, opacity=.5, showlegend = True)
# Update
fig.update_xaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True,
zeroline=False, zerolinewidth=1, zerolinecolor='Black', range= [0,0.014],
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_yaxes(showline=True, linewidth=1, linecolor='Lightgray', mirror=True, range= [0,0.1],
zeroline=False, zerolinewidth=1, zerolinecolor='Black', title_text='Value',
showgrid=True, gridwidth=1, gridcolor='Lightgray')
fig.update_layout(legend_orientation='v', plot_bgcolor= 'white', height= 500)
fig.show()
print("""The current trend seems to output a value between %.2e and %.2e.
We would like to identify a stock with high return and low risk!
""" % (Temp['Expected Return'].min(),Temp['Expected Return'].max()))
The current trend seems to output a value between 5.47e-06 and 1.21e-02. We would like to identify a stock with high return and low risk!
Let's find the quantile for a stock.
qt = All_returns['BTC-USD'].quantile(0.05)
qt_pct = abs(All_returns['BTC-USD'].quantile(0.05))*100
print('Quantile Percentage: %0.4f' % qt_pct)
print("""The 0.05 empirical quantile of daily returns is at {0:.2f}%.
This means that with 95% confidence, the worst daily loss will not exceed {0:.2f}% (of the investment)."""
.format(qt,qt_pct))
Quantile Percentage: 4.6332
The 0.05 empirical quantile of daily returns is at -0.05%.
This means that with 95% confidence, the worst daily loss will not exceed -0.05% (of the investment).
To predict future behaviors, we can implement the Monte Carlo method (also see this [2] and this [3].
# consider a year
days = 365
# Delta t
dt = 1/365
Defining a Monte Carlo function fo the Stock price.
def stock_monte_carlo(start_price, days, mu, sigma):
'''
Function takes in stock price, number of days to run, mean and standard deviation values'''
# An emptry array
price = np.zeros(days)
# Initial Price
price[0] = start_price
# Shock and drift
shock = np.zeros(days)
drift = np.zeros(days)
# Formula: New price = Old price + Old price*(shock + drift)
for x in range(1,days):
shock[x] = np.random.normal(loc=mu*dt,scale=sigma*np.sqrt(dt))
drift[x] = mu * dt
price[x] = price[x-1] + (price[x-1] * (drift[x]+shock[x]))
return price
def Monte_Carlo_Analysis(Inp, mu, sigma, N=1e2, days = days):
# get the data for each symbol
df = Disp_Data(Inp)
# set the last entry of the open column as the starting price
start_price = df['Open'][-1]
# Ouput Figure
N = int(N)
fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(16, 8))
for run in range(100):
_ = plt.plot(stock_monte_carlo(start_price, days, mu, sigma))
_ = ax.set_xlabel('Days')
_ = ax.set_ylabel('Price')
_ = ax.set_title('Monte Carlo Analysis for %s' % Stock_Dic[Inp], weight='bold', fontsize = 16)
_ = ax.set_xlim([0,days])
return df
def Final_price_distribution_simulations(Inp, mu, sigma, N= 1e4, days = days):
# get the data for each symbol
df = Disp_Data(Inp)
# set the last entry of the open column as the starting price
start_price = df['Open'][-1]
# Simulations array
N = int(N)
simulations = np.zeros(N)
# Progress Bar
Counter = 0
Progress_Bar = progressbar.ProgressBar(maxval= N, widgets=[progressbar.Bar('#', '|', '|'), progressbar.Percentage()])
Progress_Bar.start()
for i in range(N):
simulations[i] = stock_monte_carlo(start_price, days, mu, sigma)[days-1]
Counter+=1
Progress_Bar.update(Counter)
Progress_Bar.finish()
return simulations
def Final_price_distribution_plot(simulations, Inp):
# get the data for Inp teach
df = Disp_Data(Inp)
# set the last entry of the open column as the starting price
start_price = df['Open'][-1]
# Output Figure
fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(16, 8))
q = np.percentile(simulations, 1)
_ = ax.hist(simulations, bins='auto', color = '#34495e')
_ = plt.figtext(0.75, 0.80, "Start price: $%.2f" % start_price, fontsize = 12)
_ = plt.figtext(0.75, 0.75, "Mean final price: $%.2f" % simulations.mean(), fontsize = 12)
_ = plt.figtext(0.75, 0.70, "VaR(0.99): $%.2f" % (start_price -q,), fontsize = 12)
_ = plt.figtext(0.15,0.665, "q(0.99): $%.2f" % q, fontsize = 12)
_ = ax.set_xlim()
_ = ax.axvline(x=q, linewidth=4, color='#e74c3c')
_ = ax.set_title("Final price distribution for %s after %s days" % (Stock_Dic[Inp], days), weight='bold', fontsize = 16)
Stock = 'BTC-USD'
# mean
mu = All_returns.mean()[Stock]
# standard deviation
sigma = All_returns.std()[Stock]
# Analysis
Monte_Carlo_Analysis(Stock, mu = mu, sigma = sigma)
| High | Low | Open | Close | Volume | Adj Close | Moving Ave. 10 days | Moving Ave. 20 days | Moving Ave. 60 days | |
|---|---|---|---|---|---|---|---|---|---|
| Date | |||||||||
| 2020-04-12 | 6965.616699 | 6668.259766 | 6965.616699 | 6845.037598 | 3.861931e+10 | 6845.037598 | NaN | NaN | NaN |
| 2020-04-13 | 6958.557129 | 6793.821289 | 6843.281738 | 6842.427734 | 3.411043e+10 | 6842.427734 | NaN | NaN | NaN |
| 2020-04-14 | 6928.664551 | 6633.402832 | 6845.561523 | 6642.109863 | 3.228831e+10 | 6642.109863 | NaN | NaN | NaN |
| 2020-04-15 | 7134.450684 | 6555.504395 | 6640.454102 | 7116.804199 | 4.678324e+10 | 7116.804199 | NaN | NaN | NaN |
| 2020-04-17 | 7269.956543 | 7089.247070 | 7092.291504 | 7257.665039 | 3.244719e+10 | 7257.665039 | NaN | NaN | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2021-04-08 | 58937.046875 | 57807.863281 | 58326.562500 | 58245.003906 | 4.665521e+10 | 58245.003906 | 58362.953125 | 56931.446484 | 53671.391536 |
| 2021-04-09 | 61276.664062 | 58038.707031 | 58253.777344 | 59793.234375 | 5.823847e+10 | 59793.234375 | 58450.393359 | 57044.937109 | 53893.260352 |
| 2021-04-10 | 60790.554688 | 59289.796875 | 59846.230469 | 60204.964844 | 4.628025e+10 | 60204.964844 | 58561.308984 | 57328.728125 | 54148.040039 |
| 2021-04-11 | 61253.035156 | 59589.875000 | 60175.945312 | 59893.453125 | 5.182869e+10 | 59893.453125 | 58612.223047 | 57586.453516 | 54347.775391 |
| 2021-04-13 | 63742.285156 | 59892.859375 | 60292.875000 | 63450.253906 | 6.595397e+10 | 63450.253906 | 59196.859375 | 58120.252930 | 54613.532096 |
362 rows × 9 columns
The frequencies of different outcomes simulated form a Bell curve. The most likely return is in the middle of the curve. This means there is an equal chance that the actual return will be higher or lower than that value.
Simulations = Final_price_distribution_simulations(Stock, mu = mu, sigma = sigma)
Final_price_distribution_plot(Simulations, Stock)
|#########################################################################|100%
See more details about Value at Risk (VaR) [4].